package net.grandnature.android.morse.player;

import java.io.DataOutputStream;
import java.io.IOException;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

public class MorseSoundPlayer implements MorsePlayer {
	public static final int SamplingFreq = 16000;
	private short[] shortSound;
	private short[] longSound;
	private short[] silentShortSound;
	
	private AudioTrack audioTrack;
	private DataOutputStream out;
	public MorseSoundPlayer(double freq, int shortTime){		
		int shortSample = (SamplingFreq * shortTime)/1000;
		this.shortSound = new short[shortSample];
		this.longSound = new short[shortSample*3];
		this.silentShortSound = new short[shortSample];
		double t = 0.0;
		double dt = 1.0 / SamplingFreq;
		for (int i = 0; i < shortSound.length; i++, t += dt) {
			shortSound[i] = (short) (Short.MAX_VALUE * Math.sin(2.0 * Math.PI * t * freq));
		}
		for (int i = 0; i < longSound.length; i++, t += dt) {
			longSound[i] = (short) (Short.MAX_VALUE * Math.sin(2.0 * Math.PI * t * freq));
		}
		int buffSize = AudioTrack.getMinBufferSize(SamplingFreq, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
		this.audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
				SamplingFreq,
				AudioFormat.CHANNEL_CONFIGURATION_MONO,
				AudioFormat.ENCODING_PCM_16BIT,
				buffSize,
				AudioTrack.MODE_STREAM);
		this.audioTrack.play();
		
		
	}
	public void setDataOutputStream(DataOutputStream out) {
		this.out = out;
	}
	private void writeToOut(short[] d) {
		try {
			for (short s : d) {
					out.writeShort(s);
			}
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	public void longSignal() {
		this.audioTrack.write(this.longSound, 0, this.longSound.length);
		this.audioTrack.flush();
		if(out!=null) {
			writeToOut(this.longSound);
		}
	}

	@Override
	public void shorSignal() {
		this.audioTrack.write(this.shortSound, 0, this.shortSound.length);
		this.audioTrack.flush();
		if(out!=null) {
			writeToOut(this.shortSound);
		}
	}

	@Override
	public void silent(int length) {
		for(int i=0; i<length; i++){
			this.audioTrack.write(this.silentShortSound, 0, this.silentShortSound.length);
		}
		this.audioTrack.flush();
		if(out!=null) {
			writeToOut(this.silentShortSound);
		}
	}

	@Override
	public void close() throws IOException {
		this.audioTrack.flush();
		this.audioTrack.stop();
	}
}
